#include "rc522.h"
#include "MQTT_Client.h"

MFRC522 rfid(SS_PIN, RST_PIN);
CommandState currentState = IDLE;
String inputCommand = "";
byte nuidPICC[4];

static unsigned long lastCardTime = 0;   // 防抖用

void handleSerialInput() {
    while (Serial.available()) {
        char c = Serial.read();
        if (c == '\n') {
            inputCommand.trim();
            if (inputCommand.length() > 32) inputCommand = "";
            processCommand(inputCommand);
            inputCommand = "";
            return;
        } else {
            if (inputCommand.length() < 32) inputCommand += c;
        }
    }
}

void processCommand(String cmd) {
    cmd.toLowerCase();
    if (cmd == "write") {
        currentState = WAITING_CARD;
        Serial.println("请刷卡以注册卡号...");
    }
    else if (cmd == "read") {
        printAllRegisteredCards();
    }
    else if (cmd == "delete") {
        deleteAllCards();
        Serial.println("所有卡号已删除");
    }
    else if (cmd.startsWith("delete ")) {
        byte uid[4];
        if (sscanf(cmd.c_str(), "delete %hhx %hhx %hhx %hhx",
                   &uid[0], &uid[1], &uid[2], &uid[3]) == 4) {
            if (deleteSingleCard(uid))
                Serial.println("单卡删除成功");
            else
                Serial.println("未找到该卡");
        } else {
            Serial.println("格式：delete 0x12 0x34 0x56 0x78");
        }
    }
    else {
        Serial.println("未知命令，请重试");
    }
}

void readAndProcessCard() {
    if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
        return;

    if (millis() - lastCardTime < 2000) return;   // 2 s 防抖
    lastCardTime = millis();

    if (rfid.uid.size != 4) return;   // 仅处理 4 字节 UID

    memcpy(nuidPICC, rfid.uid.uidByte, 4);

    if (currentState == WAITING_CARD) {
        if (isCardRegistered(nuidPICC)) {
            Serial.print("卡已存在，无需重复注册: ");
            printHex(nuidPICC, 4); Serial.println();
            sendCardStatusMQTT(nuidPICC, true);
        } else {
            if (registerCard(nuidPICC)) {
                Serial.print("卡号注册成功: ");
                printHex(nuidPICC, 4); Serial.println();
                sendCardStatusMQTT(nuidPICC, true);
            } else {
                Serial.println("注册失败，已满");
                sendCardStatusMQTT(nuidPICC, false);
            }
        }
        currentState = IDLE;
        Serial.println("请输入下一个命令:");
    } else {
        bool registered = isCardRegistered(nuidPICC);
        Serial.println(registered ? "success" : "error");
        sendCardStatusMQTT(nuidPICC, registered);
    }

    rfid.PICC_HaltA();
    rfid.PCD_StopCrypto1();
}

/* 注册新卡，带比对 */
bool registerCard(byte *uid) {
    if (isCardRegistered(uid)) return true;   // 已存在

    int emptyIdx = -1;
    for (int i = 0; i < MAX_CARDS; i++) {
        bool empty = true;
        for (int j = 0; j < CARD_SIZE; j++) {
            if (EEPROM.read(CARD_DATA_START + i * CARD_SIZE + j) != 0xFF) {
                empty = false; break;
            }
        }
        if (empty) { emptyIdx = i; break; }
    }
    if (emptyIdx == -1) return false;   // 无空位

    // 再比对一次是否需要写入
    bool changed = false;
    for (int j = 0; j < CARD_SIZE; j++) {
        int addr = CARD_DATA_START + emptyIdx * CARD_SIZE + j;
        if (EEPROM.read(addr) != uid[j]) {
            EEPROM.write(addr, uid[j]);
            changed = true;
        }
    }
    if (changed) EEPROM.commit();
    return true;
}

bool isCardRegistered(byte *uid) {
    for (int i = 0; i < MAX_CARDS; i++) {
        bool match = true;
        for (int j = 0; j < CARD_SIZE; j++) {
            if (EEPROM.read(CARD_DATA_START + i * CARD_SIZE + j) != uid[j]) {
                match = false; break;
            }
        }
        if (match) return true;
    }
    return false;
}

void printAllRegisteredCards() {
    bool found = false;
    for (int i = 0; i < MAX_CARDS; i++) {
        byte uid[4];
        bool empty = true;
        for (int j = 0; j < CARD_SIZE; j++) {
            uid[j] = EEPROM.read(CARD_DATA_START + i * CARD_SIZE + j);
            if (uid[j] != 0xFF) empty = false;
        }
        if (!empty) {
            Serial.print("卡号 "); printHex(uid, 4); Serial.println();
            found = true;
        }
    }
    if (!found) Serial.println("暂无注册的卡号");
}

void deleteAllCards() {
    for (int i = 0; i < MAX_CARDS * CARD_SIZE; i++)
        EEPROM.write(CARD_DATA_START + i, 0xFF);
    EEPROM.commit();
}

bool deleteSingleCard(byte *uid) {
    for (int i = 0; i < MAX_CARDS; i++) {
        bool match = true;
        for (int j = 0; j < CARD_SIZE; j++) {
            if (EEPROM.read(CARD_DATA_START + i * CARD_SIZE + j) != uid[j]) {
                match = false; break;
            }
        }
        if (match) {
            for (int j = 0; j < CARD_SIZE; j++)
                EEPROM.write(CARD_DATA_START + i * CARD_SIZE + j, 0xFF);
            EEPROM.commit();
            return true;
        }
    }
    return false;
}

void printHex(byte *b, byte s) {
    for (byte i = 0; i < s; i++) {
        Serial.print(b[i] < 0x10 ? " 0" : " ");
        Serial.print(b[i], HEX);
    }
}
void printDec(byte *b, byte s) {
    for (byte i = 0; i < s; i++) {
        Serial.print(b[i] < 0x10 ? " 0" : " ");
        Serial.print(b[i], DEC);
    }
}

String cardIdToString(byte *uid) {
    String cardId = "";
    for (byte i = 0; i < 4; i++) {
        if (uid[i] < 0x10) cardId += "0";
        cardId += String(uid[i], HEX);
    }
    cardId.toUpperCase();
    return cardId;
}

void sendCardStatusMQTT(byte *uid, bool isRegistered) {
    String cardId = cardIdToString(uid);
    sendCardStatus(cardId, isRegistered);
}

String getAllRegisteredCardsString() {
    String cardList = "";
    int count = 0;
    
    for (int i = 0; i < MAX_CARDS; i++) {
        byte uid[4];
        bool empty = true;
        for (int j = 0; j < CARD_SIZE; j++) {
            uid[j] = EEPROM.read(CARD_DATA_START + i * CARD_SIZE + j);
            if (uid[j] != 0xFF) empty = false;
        }
        if (!empty) {
            if (count > 0) cardList += ",";
            cardList += cardIdToString(uid);
            count++;
        }
    }
    return cardList;
}